The code I end up with is Program Exercise 8.2. Yours might be even better. I have left all the original code still there (although I will probably have to remove some of it later). When the button is held down the message changes and the counter updates.
I have managed to get the display to count up a value of 2 by quickly pressing and releasing it, but my experiments have convinced me that I have enough time resolution to make the program work. (in fact there is almost a game in seeing how small you can make the number - but this would result in a broken switch after a little while). If I hold down the switch I notice that the counter reaches 200 in a second, so the interrupt rate is correct.
/* Ex 8.2 Reaction Timer */
/* David Miles April 2006 */
#include <system.h>
#include <lcdlib.h>
void setup_hardware (void)
{
/* Set PortA to use digital inputs */
ANSELA = 0x00;
/* bits 0-4 of PORTA for input */
TRISA = 0x1f ;
/* Configure the INTCON register */
/* to enable timer interrupts */
INTCON = 0b10100000;
/* Configure the timer to use the prescaler */
OPTION_REG = 0b01000100 ;
}
int time_count = 0 ;
void tmrHandler( void )
{
/* increment the timer if the */
/* button is held down */
if ( PORTA & 0x01 ) {
time_count = time_count + 1 ;
}
}
/* This is the interrupt handler */
/* It is called when the PICmicro */
/* detects an interrupt */
/* It checks the status bits to */
/* find out who caused the */
/* interrupt and then calls that */
/* handler */
unsigned char counter = 0;
void interrupt( void )
{
/* if the timer has overflowed */
/* bit 2 of INTCON is set high */
if( INTCON & 4 )
{
/* clear the bit to turn */
/* off this interrupt */
clear_bit( INTCON, 2 );
counter = counter + 1;
if ( counter > 2 )
{
counter = 0;
/* call the handler */
/* function */
tmrHandler();
}
}
}
void display_value ( int value )
{
unsigned char hunds, tens, units ;
/* first get the digits */
units = value % 10 ;
value = value / 10 ;
tens = value % 10 ;
value = value / 10 ;
hunds = value % 10 ;
/* now display them */
lcd_print_ch ( '0' + hunds ) ;
lcd_print_ch ( '0' + tens ) ;
lcd_print_ch ( '0' + units ) ;
}
const unsigned char down [5] =
{
'd','o','w','n',0x00
} ;
const unsigned char up [5] =
{
'u','p',' ',' ',0x00
} ;
void main ( void )
{
lcd_start () ;
setup_hardware () ;
while (1)
{
lcd_cursor ( 0, 0 ) ;
if ( PORTA & 0x01 )
{
lcd_print ( down ) ;
}
else
{
lcd_print ( up ) ;
}
display_value ( time_count ) ;
}
}